package top.pmwly.rememberme.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.WebSecurityEnablerConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import top.pmwly.rememberme.hadler.MyAccessDeniedHandler;
import top.pmwly.rememberme.hadler.MyAuthentiactionFailurHandler;
import top.pmwly.rememberme.service.LoginServiceImpl;

import javax.sql.DataSource;

/**
 * @author Herther
 * @version 1.0.0
 * @ClassName SpringSecurity.java
 * @Description springSecurity 配置类
 * @createTime 2021年08月19日 17:03:00
 */
@Configuration
public class SpringSecurity extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;
    @Autowired
    private LoginServiceImpl loginServiceImpl;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private PersistentTokenRepository getPersistentTokenRepository;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .successForwardUrl("/toMain")
                .usernameParameter("username")
                .passwordParameter("password")
                .failureHandler(new MyAuthentiactionFailurHandler("/error.html"));

        //授权
        http.authorizeRequests()
                .antMatchers("/login.html").permitAll()
                .antMatchers("/error.html").permitAll()
                .anyRequest().authenticated();

        //关闭crs防火墙
        http.csrf().disable();

        //异常权限处理
        http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);

        //添加rememberme
        http.rememberMe()
                //失效时间
                .tokenValiditySeconds(60)
                //.rememberMeParameter("reme")
                //自定义的业务服务
                .userDetailsService(loginServiceImpl)
                //持久层
                .tokenRepository(getPersistentTokenRepository);
    }

    @Bean
    public PersistentTokenRepository getPersistentTokenRepository(){
        //PersistentTokenRepository是一个接口，不能直接new 只能new它的实现类
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        //配置数据源  //从配置文件中注入
        jdbcTokenRepository.setDataSource(dataSource);
        //自动建表，首次启动会自动建表，如果再次启动，必须把它注释了否则会出现异常
        //jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }

    /**
     * 密码解析器
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
